home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / cfengine-1.5.3 / src / 2Dlist.c next >
Encoding:
C/C++ Source or Header  |  1999-04-06  |  6.4 KB  |  307 lines

  1. /* cfengine for GNU
  2.  
  3.         Copyright (C) 1995/6
  4.         Free Software Foundation, Inc.
  5.  
  6.    This file is part of GNU cfengine - written and maintained 
  7.    by Mark Burgess, Dept of Computing and Engineering, Oslo College,
  8.    Dept. of Theoretical physics, University of Oslo
  9.  
  10.    This program is free software; you can redistribute it and/or modify it
  11.    under the terms of the GNU General Public License as published by the
  12.    Free Software Foundation; either version 2, or (at your option) any
  13.    later version.
  14.  
  15.    This program is distributed in the hope that it will be useful,
  16.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.    GNU General Public License for more details.
  19.  
  20.   You should have received a copy of the GNU General Public License
  21.   along with this program; if not, write to the Free Software
  22.   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  23.  
  24. */
  25.  
  26.  
  27. /*********************************************************************/
  28. /*                                                                   */
  29. /*  TOOLKIT: the "2Dlist" object library for cfengine                */
  30. /*           uses (inherits) item.c                                  */
  31. /*                                                                   */
  32. /*********************************************************************/
  33.  
  34. #include "cf.defs.h"
  35. #include "cf.extern.h"
  36.  
  37. /* private */
  38.  
  39. #define TD_wrapped   1
  40. #define TD_nowrap    2
  41.  
  42. /*********************************************************************/
  43. /* TOOLKIT : 2D list                                                 */
  44. /*********************************************************************/
  45.  
  46. Set2DList(list)
  47.  
  48. struct TwoDimList *list;
  49.  
  50. { struct TwoDimList *tp;
  51.  
  52. Debug1("Set2DLIst()\n");
  53.  
  54. for (tp = list; tp != NULL; tp=tp->next)
  55.    {
  56.    tp->current = tp->ilist;
  57.    }
  58. }
  59.  
  60. /*********************************************************************/
  61.  
  62. char *Get2DListEnt(list)
  63.  
  64.    /* return a path string in static data, like getent in NIS */
  65.  
  66. struct TwoDimList *list;
  67.  
  68. { static char entry[bufsize];
  69.   struct TwoDimList *tp;
  70.   struct Item *ip;
  71.   char seps[2], *sp;
  72.  
  73. Debug1("Get2DListEnt()\n");
  74.  
  75. if (EndOfTwoDimList(list))
  76.    {
  77.    return NULL;
  78.    }
  79.  
  80. bzero(entry,bufsize);
  81.  
  82. for (tp = list; tp != NULL; tp=tp->next)
  83.    {
  84.    sprintf(seps,"%c",tp->sep);
  85.  
  86.    if (tp->current != NULL)
  87.       {
  88.       strcat(entry,(tp->current)->name);
  89.       }
  90.    }
  91.  
  92.  
  93. Debug1("Get2DLIstEnt returns %s\n",entry);
  94.  
  95. IncrementTwoDimList(list,list);
  96.  
  97. return entry;
  98. }
  99.  
  100. /*********************************************************************/
  101.  
  102. Build2DListFromVarstring(TwoDimlist,varstring,sep)
  103.  
  104.  /* Build a database list with all expansions of a 2D list a */
  105.  /* sep is a separator which is used to split a many-variable */
  106.  /* string into many strings with only one variable           */
  107.  
  108. struct TwoDimList **TwoDimlist;
  109. char *varstring, sep;
  110. /* GLOBAL LISTSEPARATOR */
  111.  
  112. { char format[6], *sp;
  113.   char node[maxlinksize];
  114.   int i;
  115.  
  116. Debug1("Build2DListFromVarstring(%s,sep=%c)\n",varstring,sep);
  117.  
  118. if ((strlen(varstring) == 1) && (varstring[0] == sep))
  119.    {
  120.    AppendTwoDimItem(TwoDimlist,SplitVarstring("",'$'),sep);
  121.    return;
  122.    }
  123.  
  124. sprintf(format,"%%[^%c]",sep);   /* set format string to search */
  125.  
  126. for (sp = varstring; *sp != '\0'; sp++)
  127.    {
  128.    bzero(node,maxlinksize);
  129.  
  130.    *node = *sp;;
  131.       
  132.    for (i = 1; (*(sp+i) != '$') && (*(sp+i) != '\0'); i++)
  133.       {
  134.       *(node+i) = *(sp+i);
  135.       }
  136.  
  137.       *(node+i) = '\0';
  138.       sp += i-1;
  139.    
  140.    if (strlen(node) == 0)
  141.       {
  142.       continue;
  143.       } 
  144.    
  145.    AppendTwoDimItem(TwoDimlist,SplitVarstring(node,LISTSEPARATOR),sep);
  146.  
  147.    if (*sp == '\0')
  148.       {
  149.       break;
  150.       }
  151.    }
  152. }
  153.  
  154. /*********************************************************************/
  155.  
  156. IncrementTwoDimList (from,list)
  157.  
  158. struct TwoDimList *from, *list;
  159.  
  160. { struct TwoDimList *tp;
  161.  
  162. Debug1("IncrementTwoDimList()\n");
  163.  
  164. for (tp = from; tp != NULL; tp=tp->next)
  165.    {
  166.    if (tp->is2d)
  167.       {
  168.       break;
  169.       }
  170.    }
  171.  
  172. if (tp == NULL)
  173.    {
  174.    return TD_wrapped;
  175.    }
  176.  
  177. if (IncrementTwoDimList(tp->next,list) == TD_wrapped)
  178.    {
  179.    tp->current = (tp->current)->next;
  180.  
  181.    if (tp->current == NULL)
  182.       {
  183.       tp->current = tp->ilist;
  184.       tp->rounds++;             /* count iterations to ident eolist*/
  185.       return TD_wrapped;
  186.       }
  187.    else
  188.       {
  189.       return TD_nowrap;
  190.       }
  191.    }
  192.  
  193. return TD_nowrap; /* Shouldn't get here */
  194. }
  195.  
  196. /*********************************************************************/
  197.  
  198. EndOfTwoDimList(list)       /* bool */
  199.  
  200. struct TwoDimList *list;
  201.  
  202.    /* returns true if the leftmost list variable has cycled */
  203.    /* i.e. rounds is > 0 for the first is-2d list item      */
  204.  
  205. { struct TwoDimList *tp;
  206.  
  207. for (tp = list; tp != NULL; tp=tp->next)
  208.    {
  209.    if (tp->is2d)
  210.        {
  211.        break;
  212.        }
  213.    }
  214.  
  215. if (list == NULL)
  216.    {
  217.    return true;
  218.    }
  219.  
  220. if (tp == NULL)             /* Need a case when there are no lists! */
  221.    {
  222.    if (list->rounds == 0)
  223.       {
  224.       list->rounds = 1;
  225.       return false;
  226.       }
  227.    else
  228.       {
  229.       return true;
  230.       }
  231.    }
  232.  
  233. if (tp->rounds > 0)
  234.     {
  235.     return true;
  236.     }
  237. else
  238.     {
  239.     return false;
  240.     }
  241. }
  242.  
  243. /*********************************************************************/
  244.  
  245. AppendTwoDimItem(liststart,itemlist,sep)
  246.  
  247. struct TwoDimList **liststart;
  248. struct Item *itemlist;
  249. char sep;
  250.  
  251. { struct TwoDimList *ip, *lp;
  252.  
  253. Debug1("AppendTwoDimItem(itemlist, sep=%c)\n",sep);
  254.  
  255. if ((ip = (struct TwoDimList *)malloc(sizeof(struct TwoDimList))) == NULL)
  256.    {
  257.    CfLog(cferror,"AppendTwoDimItem","malloc");
  258.    FatalError("");
  259.    }
  260.  
  261. if (*liststart == NULL)
  262.    {
  263.    *liststart = ip;
  264.    }
  265. else
  266.    {
  267.    for (lp = *liststart; lp->next != NULL; lp=lp->next)
  268.       {
  269.       }
  270.  
  271.    lp->next = ip;
  272.    }
  273.  
  274. ip->ilist = itemlist;
  275. ip->current = itemlist; /* init to start of list */
  276. ip->next = NULL;
  277. ip->rounds = 0;
  278. ip->sep = sep;
  279.  
  280. if (itemlist == NULL || itemlist->next == NULL)
  281.    {
  282.    ip->is2d = false;
  283.    }
  284. else
  285.    {
  286.    ip->is2d = true;
  287.    }
  288. }
  289.  
  290. /*********************************************************************/
  291.  
  292. Delete2DList(item)
  293.  
  294. struct TwoDimList *item;
  295.  
  296. {
  297. if (item != NULL)
  298.    {
  299.    Delete2DList(item->next);
  300.    item->next = NULL;
  301.  
  302.    DeleteItemList(item->ilist);
  303.    
  304.    free((char *)item);
  305.    }
  306. }
  307.